EventBridgeのSchema Registry コードバインディング機能でS3イベント処理を楽に実装する
もう一ヶ月も前の話ですが、EventBridge Schema Registry がGAになりました!
EventBridge schema registryって?
各種イベントのスキーマ(≒構造、定義、形式)を格納する場所、です。
EventBridgeはイベントを発行したり、発行されたイベントをフィルタリングし、所定のイベントが発生した場合のみLambda関数実行など特定の処理を実施することができます。このイベントの発行、フィルタリング、またイベントを受け取ったターゲット内の処理にてイベントのスキーマを理解している必要があります。例えば間違ったスキーマのイベントを発行すると、受け取る側が正しくフィルタリングや処理ができませんよね。そこで一元的にイベントスキーマを管理する場所として用意されたのがEventBridge schema registryです。EventBridgeとネイティブに統合できる各種AWSサービスのイベントや、SaaSアプリケーションのイベント、また独自のイベントを定義することもできます。
また、コードバインディング機能があります。これはschema registryで閲覧できる各イベントスキーマのJava・Python・TypeScriptのコードバインディング をダウンロードできる機能です。これを利用すればより簡単にイベント駆動処理のコードが書けます。
やってみた
例として、S3イベントがSchema Registryでどんな感じなのか見てみます。
※ここでいうS3イベントとは、S3のコンソールから設定できるS3イベント通知機能で発行されるイベントではありません。こちらはEventBridgeを介さず、S3から直接他サービス(Lambdaなど)に連携されるものです。そうではなく、今回はEventBridgeを使ってS3イベントをキャプチャし、他サービスをトリガーする処理について見ていきます。このあたりの話については以下エントリの冒頭部分をご参考ください。
スキーマレジストリ > スキーマに移動
AWS Toolkitからも利用できる
VS CodeのExtensionであるAWS Toolkitからもスキーマレジストリを利用できます。
S3のスキーマもありましたね。マネージドコンソールと同じくスキーマとコードバインディングのダウンロードが可能です。
ダウンロードされたファイル群(TypeScript)を見てみる
$ tree ./ ./ ├── README.md └── schema └── aws └── s3 └── awsapicallviacloudtrail ├── AWSAPICallViaCloudTrail.ts ├── AWSEvent.ts ├── AdditionalEventData.ts ├── Attributes.ts ├── LegalHoldInfo.ts ├── ObjectRetentionInfo.ts ├── RequestParameters.ts ├── RetentionInfo.ts ├── SessionContext.ts ├── UserIdentity.ts └── marshaller └── marshaller.ts
大量のファイルがありますが心配ありません。ここで重要なのはAWSEvent.ts
とAWSAPICallViaCloudTrail.ts
だけです。あとのファイルはAWSAPICallViaCloudTrail.ts
でimportされるファイルです。
※ marshaller/marshaller.ts
だけ今ひとつ使い方がわかりませんでした。。どなたか教えて下さい!
AWSEvent.ts
AWSEventクラスが定義されています。
(EventBridgeで扱う)AWSイベントはすべて、最上位のフィールドが同じになっています。この全AWSイベント共通の部分のスキーマを扱っているのがこのクラスです。プロパティは以下です。
'detail': T; 'detail_type': string; 'resources': Array<string>; 'id': string; 'source': string; 'time': Date; 'region': string; 'version': string; 'account': string;
detail
以下が、イベント種別毎に異なる形式になります。
※ detail
値がT
になっていますが、これはクラスが class AWSEvent<T>
となっているので、つまりクラス使用時に型を決める ジェネリックです。
参考情報
AWSAPICallViaCloudTrail.ts
今回のS3イベントの場合は、AWSEvent
クラスdetail
プロパティ以下がこちらのAWSAPICallViaCloudTrail
クラスの形式になります。EventBridgeでS3イベントをキャプチャする場合は、S3とEventBridgeを直接連携するのではなく、一度CloudTrail認証に記録したログをEventBridgeで拾う形になります。
このクラスは以下プロパティを持っています。RequestParameters
、UserIdentity
、AdditionalEventData
はダウンロードした他のファイルに書かれています。
'requestParameters': RequestParameters; 'userIdentity': UserIdentity; 'additionalEventData': AdditionalEventData; 'eventID': string; 'awsRegion': string; 'eventVersion': string; 'responseElements': any; 'sourceIPAddress': string; 'eventSource': string; 'errorMessage': string; 'resources': Array<any>; 'errorCode': string; 'userAgent': string; 'readOnly': boolean; 'eventType': string; 'vpcEndpointId': string; 'requestID': string; 'eventTime': Date; 'eventName': string; 'recipientAccountId': string;
たとえば、S3イベントの種類(PutObjectなど)はeventName
に現れますし、対象バケットやキー値はrequestParameters
以下やresources
以下に記録されます。
参考情報
使用例
S3イベントを受けてLambda関数で何かしらの処理を行なう場合を考えます。
export async function handler( event: any ): Promise<any> { console.log("LogS3DataEvents"); const response = JSON.stringify(event, null, 2); return response; };
イベント対象のオブジェクトに対して何かしら処理をする場合、例えば event.detail.requestParameters.bucketName
のバケット名とevent.detail.requestParameters.key
のオブジェクトキーを使って処理を組み立てるのですが、このままではそのフィールドにたどり着くのは大変です。
ということで引数event
にクラスを充てます。
import { AWSEvent } from "./schema/aws/s3/awsapicallviacloudtrail/AWSEvent"; import { AWSAPICallViaCloudTrail } from "./schema/aws/s3/awsapicallviacloudtrail/AWSAPICallViaCloudTrail"; export async function handler( event: AWSEvent<AWSAPICallViaCloudTrail> ): Promise<any> { console.log("LogS3DataEvents"); const response = JSON.stringify(event, null, 2); return response; };
こうすることでVSCodeの型補完の恩恵を受けながらコーディング可能になります。
まとめ
EventBridge Schema Registry、そのなかでもコードバインディングについて、S3イベントを例にとってご紹介しました。AWSでイベントドリブンアーキテクチャーのアプリケーションの実装をする際に非常に役立つと思います。ぜひ利用をご検討ください。